using Emgu.CV;
using SkiaSharp;
using System;
using System.IO;
using System.Runtime.InteropServices;
using Emgu.CV.CvEnum;

namespace DualCameraApp.Services;

public class ImageConverterService
{
    public static Avalonia.Media.Imaging.Bitmap? ConvertMatToAvaloniaBitmapByDraw(Mat mat)
    {
        if (mat == null || mat.IsEmpty)
            return null;

        try
        {
            using var memoryStream = new MemoryStream();
            
            // 将Mat转换为System.Drawing.Bitmap
            using var bitmap = mat.ToBitmap();
            
            // 保存到内存流
            bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
            memoryStream.Seek(0, SeekOrigin.Begin);
            
            // 创建Avalonia Bitmap
            return new Avalonia.Media.Imaging.Bitmap(memoryStream);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"图像转换失败: {ex.Message}");
            return null;
        }
    }
    
    public static Avalonia.Media.Imaging.Bitmap? ConvertBitmapToAvaloniaBitmap(System.Drawing.Bitmap bitmap)
    {
        if (bitmap == null)
            return null;

        try
        {
            using var memoryStream = new MemoryStream();
            bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
            memoryStream.Seek(0, SeekOrigin.Begin);
            return new Avalonia.Media.Imaging.Bitmap(memoryStream);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"图像转换失败: {ex.Message}");
            return null;
        }
    }
    
    public static Avalonia.Media.Imaging.Bitmap? ConvertMatToAvaloniaBitmapBySkia(Mat mat)
    {
        if (mat == null || mat.IsEmpty)
            return null;

        try
        {
            // 使用纯SkiaSharp方式进行转换
            // using var skBitmap = MatToSKBitmapUnsafe(mat);
            using var skBitmap = MatToSKBitmapSafe(mat);
            if (skBitmap == null)
                return null;

            // 将SKBitmap转换为Avalonia Bitmap
            return SKBitmapToAvaloniaBitmap(skBitmap);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"图像转换失败: {ex.Message}");
            return null;
        }
    }

    public static SKBitmap MatToSKBitmapSafe(Mat mat)
    {
        if (mat.IsEmpty)
            return null;

        // 确保输入矩阵是8位3通道
        if (mat.Depth != DepthType.Cv8U || mat.NumberOfChannels != 3)
            throw new ArgumentException("输入矩阵必须是8位3通道(BGR)图像");

        // 转换BGR到RGB
        Mat rgbMat = new Mat();
        CvInvoke.CvtColor(mat, rgbMat, ColorConversion.Bgr2Rgb);

        // 创建4通道RGBA的SKBitmap
        SKBitmap bitmap = new SKBitmap(rgbMat.Cols, rgbMat.Rows, SKColorType.Rgba8888, SKAlphaType.Opaque);

        using (SKPixmap pixmap = bitmap.PeekPixels())
        {
            // 获取Mat的字节数组
            byte[] matData = new byte[rgbMat.Rows * rgbMat.Cols * 3];
            System.Runtime.InteropServices.Marshal.Copy(rgbMat.DataPointer, matData, 0, matData.Length);

            // 获取SKBitmap的像素指针
            IntPtr pixelsPtr = pixmap.GetPixels();
            byte[] skData = new byte[pixmap.BytesSize];
            System.Runtime.InteropServices.Marshal.Copy(pixelsPtr, skData, 0, skData.Length);

            // 转换3通道RGB到4通道RGBA（添加alpha通道）
            for (int i = 0, j = 0; i < matData.Length; i += 3, j += 4)
            {
                skData[j] = matData[i]; // R
                skData[j + 1] = matData[i + 1]; // G
                skData[j + 2] = matData[i + 2]; // B
                skData[j + 3] = 0xFF; // A (不透明)
            }

            // 将处理好的数据复制回SKBitmap
            System.Runtime.InteropServices.Marshal.Copy(skData, 0, pixelsPtr, skData.Length);
        }

        return bitmap;
    }


    public static SKBitmap MatToSKBitmapUnsafe(Mat mat)
    {
        if (mat.IsEmpty)
            return null;

        // 确保输入矩阵是8位3通道
        if (mat.Depth != DepthType.Cv8U || mat.NumberOfChannels != 3)
            throw new ArgumentException("输入矩阵必须是8位3通道(BGR)图像");

        int width = mat.Cols;
        int height = mat.Rows;
        int pixelCount = width * height;

        // 创建4通道RGBA的SKBitmap
        SKBitmap bitmap = new SKBitmap(width, height, SKColorType.Rgba8888, SKAlphaType.Opaque);

        using (SKPixmap pixmap = bitmap.PeekPixels())
        {
            // 锁定SKBitmap的像素内存
            IntPtr skPtr = pixmap.GetPixels();

            // 直接在非托管内存中进行转换
            unsafe
            {
                byte* bgrPtr = (byte*)mat.DataPointer;
                byte* rgbaPtr = (byte*)skPtr;

                // 并行处理行以提高性能
                System.Threading.Tasks.Parallel.For(0, height, y =>
                {
                    int rowOffset = y * mat.Cols * 3; // BGR行偏移量
                    int rgbaRowOffset = y * pixmap.RowBytes; // RGBA行偏移量

                    for (int x = 0; x < width; x++)
                    {
                        int bgrIndex = rowOffset + x * 3;
                        int rgbaIndex = rgbaRowOffset + x * 4;

                        // BGR转RGBA (OpenCV是BGR顺序，SKBitmap是RGBA)
                        rgbaPtr[rgbaIndex] = bgrPtr[bgrIndex + 2]; // R
                        rgbaPtr[rgbaIndex + 1] = bgrPtr[bgrIndex + 1]; // G
                        rgbaPtr[rgbaIndex + 2] = bgrPtr[bgrIndex]; // B
                        rgbaPtr[rgbaIndex + 3] = 0xFF; // A (不透明)
                    }
                });
            }
        }

        return bitmap;
    }


    private static Avalonia.Media.Imaging.Bitmap? SKBitmap2AvaloniaBitmap(SKBitmap skBitmap)
    {
        if (skBitmap == null)
            return null;

        try
        {
            using var memoryStream = new MemoryStream();

            // 编码为PNG
            using var skImage = SKImage.FromBitmap(skBitmap);
            using var skData = skImage.Encode(SKEncodedImageFormat.Png, 100);

            if (skData == null)
                return null;

            skData.SaveTo(memoryStream);
            memoryStream.Seek(0, SeekOrigin.Begin);

            return new Avalonia.Media.Imaging.Bitmap(memoryStream);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"SKBitmap到Avalonia转换失败: {ex.Message}");
            return null;
        }
    }

    private static Avalonia.Media.Imaging.Bitmap? SKBitmapToAvaloniaBitmap(SKBitmap skBitmap)
    {
        if (skBitmap == null || skBitmap.IsNull || skBitmap.Width == 0 || skBitmap.Height == 0)
            return null;

        try
        {
            // 直接使用SKImage进行编码，避免不必要的复制
            using var skImage = SKImage.FromBitmap(skBitmap);
            if (skImage == null)
                return null;

            // 使用无压缩的BMP格式可以显著提高编码速度（如果需要快速显示）
            // 或者保持PNG但调整质量参数（如果需要透明度）
            using var skData = skImage.Encode(SKEncodedImageFormat.Png, 85);
            if (skData == null || skData.IsEmpty)
                return null;

            // 预分配正确大小的内存流
            using var memoryStream = new MemoryStream((int)skData.Size);
            skData.SaveTo(memoryStream);
            memoryStream.Seek(0, SeekOrigin.Begin);

            return new Avalonia.Media.Imaging.Bitmap(memoryStream);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"SKBitmap到Avalonia转换失败: {ex.Message}");
            return null;
        }
    }
}